<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>this指向</title>
  </head>
  <body>
    <script>
      // 对象上的 function 称之为方法
      // 1. 谁调用函数（方法），this 就是谁
      // const cat = {
      //   name: '布偶猫',
      //   sayHI() {
      //     console.log('喵喵喵')
      //     console.log(this)
      //   },
      //   eatFish() {
      //     console.log('喵呜，喵呜')
      //     console.log(this)
      //   },
      // }

      // cat.sayHI() // this 是 cat
      // cat.eatFish()

      // 2. 没有【显示调用】，默认是全局对象 ,浏览器中是 window
      // 在浏览器中添加的全局的变量，函数，都等同于给 window 对象添加的属性，方法
      // function eatFood() {
      //   console.log('吧唧吧唧')
      //   console.log(this)
      // }
      // // 等同于 window.eatFood = xxx
      // eatFood()

      // 3. 容易出现 this 指向混乱的情况
      // const cat = {
      //   name: '布偶猫',
      //   food: '鱼罐头',
      //   sayHI() {
      //     console.log('喵喵喵')
      //     console.log(this) // cat
      //     window.setTimeout(function () {
      //       console.log(this) // window
      //       console.log(this.food)
      //     }, 1000)
      //   },
      // }

      // cat.sayHI()

      // 4. 通过箭头函数绑定 this
      // 箭头会在创建的时候绑定当前作用域中的 this
      // 创建作用域，最常见的是函数
      const cat = {
        name: "布偶猫",
        food: "鱼罐头",
        sayHI() {
          console.log("喵喵喵");
          console.log(this); // cat
          setTimeout(() => {
            console.log(this.name);
            console.log(this.food);
          }, 1000);
        },
      };
      cat.sayHI();

      /**
       * 面试问到 this 相关：
       * 1. this 在 js 和 ts 中很灵活，谁调用就是谁
       * 2. 如果没有直接通过对象调用，是全局对象,很容易出现 this 指向丢失的问题
       * 3. 可以通过箭头函数来解决，因为箭头函数可以绑定当前作用域中的 this，保证 this 指向没有问题
       * 4. ArkTS 中我也碰到过类似的场景 BuilderParam 传递 builder 时，需要通过箭头函数包裹，目的就是为了绑定 this
       *
       * */
    </script>
  </body>
</html>
